﻿using mozhi.smarterp.AuthorCenter.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp;
using Volo.Abp.Domain.Entities;

namespace mozhi.smarterp.AuthorCenter.Permissions
{

    public class PermissionGroup : AggregateRoot<Guid>
    {
        public string Code {  get; private set; }

        public string Name { get; private set; }

        public PermissionType Type { get; private set; }

        public List<PermissionItem> Items { get; private set; }

        private PermissionGroup() { }

        public PermissionGroup(Guid id , string code, string name, PermissionType type)
        {
            Id = id;
            Code = code;
            Name = name;
            Type = type;
            Items = new List<PermissionItem>();

            Validate();
        }

        public void ChangeCodeOrName(string code, string name)
        {
            this.Code = code;
            this.Name = name;
            Validate();
        }

        public void AddItems(List<PermissionItem> items)
        {
            if (items == null)
                return;

            foreach (var item in items)
            {
                var match = Items.FirstOrDefault(x => x.Id == item.Id);

                if (match == null)
                {
                    if (Items.Exists(x => x.Code == item.Code))
                        throw new UserFriendlyException($"权限项：{item.Code}重复");

                    if(Items.Exists(x=>x.ParentId == item.ParentId && x.Name == item.Name))
                        throw new UserFriendlyException($"权限项：{item.Name}重复");

                    Items.Add(item);
                }
                else
                {
                    Items.Remove(match);
                    Items.Add(item);
                }
            }

            Items.ForEach(item =>
            {
                item.SetType(Type);
                item.SetGroupId(Id);
            });
        }

        public void RemoveItems(List<PermissionItem> items)
        {
            if (items == null)
                return;

            foreach (var item in items)
            {
                var match = Items.FirstOrDefault(x => x.Id == item.Id);

                if (match != null)
                    Items.Remove(match);
            }
        }

        #region
        private void Validate()
        {
            if (Code.IsNullOrEmpty())
                throw new ArgumentNullException(nameof(Code));

            if (Name.IsNullOrEmpty())
                throw new ArgumentNullException(nameof(Name));
        }
        #endregion
    }


    public class PermissionItem : Entity<Guid>
    {
        public Guid? ParentId { get; private set; }

        public string Code { get; private set; }

        public string Name { get; private set; }

        public PermissionType Type { get; private set; }

        public Guid? PermissionGroupId { get; private set; }

        private PermissionItem() { }

        public PermissionItem(Guid id, Guid? parentId, string code, string name, PermissionType type)
        {
            Id = id;
            ParentId = parentId;
            Code = code;
            Name = name;
            Type = type;

            Validate();
        }

        public void SetType(PermissionType type)
        {
            Type = type;
        }

        public void SetGroupId(Guid groupId)
        {
            PermissionGroupId = groupId;
        }

        public void ChangeCodeOrName(string code , string name)
        {
            this.Code = code;
            this.Name = name;
        }

        public void ChangeParentId(Guid? parentId)
        {
            this.ParentId = parentId;
        }

        #region
        private void Validate()
        {
            if (Code.IsNullOrEmpty())
                throw new ArgumentNullException(nameof(Code));

            if (Name.IsNullOrEmpty())
                throw new ArgumentNullException(nameof(Name));
        }
        #endregion
    }
}
